package ifmo.group5512.timer.client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientRunnable implements Runnable {
	public TimerClient client;
	final Object monitor = new Object();

	private String host = "127.0.0.1";
	private int port = 18080;
	Socket s;
	BufferedReader reader;
	BufferedWriter writer;

	public void initConnection() {
		try {
			s = new Socket(this.host, this.port);
			reader = new BufferedReader(new InputStreamReader(
					s.getInputStream()));
			writer = new BufferedWriter(new OutputStreamWriter(
					s.getOutputStream()));

		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	ClientRunnable(String host, int port, String type) {
		this.host = host;
		this.port = port;
		client = new TimerClient(type);
		initConnection();

	}

	private void finish() {
		if (exit) {
			closeConnection();
		}
	}

	public boolean exit = false;

	@Override
	public void run() {
		while (!exit) {
			System.out.println("new Iteration started");
			synchronized (monitor) {
				while (!client.isNeedWork() && !exit) {
					try {
						System.out.println("no need to work");
						monitor.wait();
					} catch (InterruptedException e) {
						finish();
						if (exit)
							break;
						e.printStackTrace();
					}
				}
				if (exit)
					break;
			}

			try {
				startCommunication();

				timerInput = reader.readLine();
				System.out.println(timerInput);

				if (Character.getNumericValue(timerInput.charAt(0)) > 0) {
					synchronized (monitor) {
						while (client.needWork && !exit) {
							client.canWork = true;
							monitor.notifyAll();
							try {
								monitor.wait();
							} catch (InterruptedException e) {
								finish();
								// e.printStackTrace();
							}
						}
						if (exit)
							break;
					}

					finishSending();

					String x = reader.readLine();
					System.out.println(x);

					synchronized (monitor) {
						client.canWork = false;
						monitor.notifyAll();
					}

					System.out.println("iteration finished");
				} else {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
						finish();
						if (exit)
							break;
						e1.printStackTrace();
					}
				}

			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

		}

	}

	private String type = "";
	private String timerInput = "";

	private void startCommunication() throws IOException {
		writer.write(client.getType() + "\n");
		writer.flush();
	}

	private void finishSending() throws IOException {
		writer.write(client.getType() + "end\n");
		writer.flush();
	}

	public void closeConnection() {
		try {
			s.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("exiting");
	}

	public void needWork(boolean needWork) {
		synchronized (monitor) {
			client.needWork = needWork;
			monitor.notifyAll();
		}
	}

	public boolean canWork() {
		return client.isCanWork();
	}

	public TimerClient getClient() {
		return client;
	}

	public void setClient(TimerClient client) {
		this.client = client;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getTimerInput() {
		return timerInput;
	}

	public void setTimerInput(String timerInput) {
		this.timerInput = timerInput;
	}

}
